/*通过苹果笔记本的构造理解建造者模式*/
#include<memory>
#include<iostream>
#include<string>
using namespace std;

class Computer
{
public:
    Computer()//电脑类 
    {

    }
    void setBoard(const string &board)//设置主板
    {
        _board=board;
    }

    void setDisplay(const string &display)//设置显示器
    {
        _display=display;
    }
    void showParamaters()//显示电脑参数
    {
        string param="Computer Parameters:\n";
        param+="\tBoard:"+_board+"\n";
        param+="\tDisplay:"+_display+"\n";
        param+="\tOs:"+_os+"\n";
        cout<<param<<endl;
    }
    virtual void setOS()=0; 
protected:
    string _board;//主板
    string _display;//显示器
    string _os;//操作系统

};

class MacBook :public Computer//苹果电脑类
{
public:
    
    void setOS()override
    {
        _os="Mac OS x12";//不能访问父类的私有成员
    }

};

class Builder//创造者类
{
public:
    virtual void buildBoard(const string &board)=0;
    virtual void builddisplay(const string &display)=0;
    virtual void buildOs()=0;
    virtual shared_ptr<Computer> build()=0;
};

class MacBookBuilder :public Builder//基于创造者的苹果笔记本创建者类
{
public:
    MacBookBuilder()
    :_computer(new MacBook()){}
    void buildBoard(const string &board)//对这个电脑类对象的主板进行设置
    {
        _computer->setBoard(board);
    }
    void builddisplay(const string &display)//对这个电脑类对象的显示器进行设置
    {
        _computer->setDisplay(display);
    }
    void buildOs()//对这个电脑类对象的操作系统进行设置
    {
        _computer->setOS();//这里我们setOs里面已经设置好了笔记本的型号了
    }
    shared_ptr<Computer> build()//返回一个笔记本类对象
    {
        return _computer;
    }

private:
    shared_ptr<Computer>_computer;//构建一个电脑类
};

//上面这个类就是创建零部件然后返回最终的电脑对象


//下面我们还需要一个指挥家类的对象，因为可能零部件配置的顺序是不一样的
class Director
{
public:
    Director(Builder *builder)//传进来一个builder对象
    :_builder(builder)
    {}

    void construct(string board,string display)//指挥家类对象来配置零部件,需要传入一个显示器和主板的对象
    {
        _builder->buildBoard(board);//设置主板
        _builder->builddisplay(display);//设置显示器
        _builder->buildOs();//设置操作系统
    }
private:
    shared_ptr<Builder>_builder;//一个Builder对象


};

int main()
{
    Builder *builder=new MacBookBuilder();//创建一个苹果笔记本电脑
    unique_ptr<Director>director(new Director(builder));//创建一个指挥家类对象
    director->construct("华硕主板","苹果显示器");//指挥家类对象来配置零部件
    shared_ptr<Computer>computer=builder->build();//返回一个笔记本类对象
    computer->showParamaters();
    return 0;
}


